/**
 * 音频处理工具类
 * 后端直接处理麦克风，前端只发送控制消息
 */

export interface AudioRecognitionResult {
  type: 'recognition_result' | 'recognition_started' | 'recognition_ended' | 'recognition_complete' | 'error' | 'initialized' | 'recording_started' | 'recording_stopped'
  text?: string
  is_final?: boolean
  confidence?: number
  begin_time?: number
  end_time?: number
  request_id?: string
  usage?: any
  message?: string
  session_id?: string
}

export interface AudioRecognitionConfig {
  model?: string
  format?: string
  sample_rate?: number
  language_hints?: string[]
  channels?: number
}

export class AudioRecognitionClient {
  private ws: WebSocket | null = null
  private sessionId: string
  private config: AudioRecognitionConfig
  private isRecording = false
  private onResult: (result: AudioRecognitionResult) => void
  private onError: (error: string) => void
  private onStatusChange: (status: 'connecting' | 'connected' | 'recording' | 'stopped' | 'error') => void

  constructor(
    sessionId: string,
    config: AudioRecognitionConfig = {},
    onResult: (result: AudioRecognitionResult) => void,
    onError: (error: string) => void = console.error,
    onStatusChange: (status: 'connecting' | 'connected' | 'recording' | 'stopped' | 'error') => void = () => {}
  ) {
    this.sessionId = sessionId
    // 配置主要由后端处理
    this.config = {
      model: 'paraformer-realtime-v2',
      format: 'pcm',
      sample_rate: 16000,
      language_hints: ['zh'],
      channels: 1,
      ...config
    }
    this.onResult = onResult
    this.onError = onError
    this.onStatusChange = onStatusChange
  }

  /**
   * 连接WebSocket服务
   */
  async connect(): Promise<void> {
    return new Promise((resolve, reject) => {
      try {
        this.onStatusChange('connecting')
        
        // 创建WebSocket连接
        const wsUrl = `${this.getWebSocketUrl()}/api/audio/ws/recognition/${this.sessionId}`
        console.log('🔗 尝试连接WebSocket:', wsUrl)
        console.log('📊 连接参数:', {
          sessionId: this.sessionId,
          config: this.config,
          protocol: window.location.protocol,
          hostname: window.location.hostname,
          port: window.location.port
        })
        
        this.ws = new WebSocket(wsUrl)

        this.ws.onopen = () => {
          console.log('✅ WebSocket连接已建立，等待后端初始化')
          console.log('🔍 WebSocket状态:', this.ws?.readyState)
        }

        this.ws.onmessage = (event) => {
          try {
            console.log('📨 收到WebSocket消息:', event.data)
            const result: AudioRecognitionResult = JSON.parse(event.data)
            
            if (result.type === 'initialized') {
              console.log('🎉 音频识别会话已初始化', result)
              this.onStatusChange('connected')
              resolve()
            } else if (result.type === 'recording_started') {
              console.log('🎤 后端开始录音')
              this.isRecording = true
              this.onStatusChange('recording')
              this.onResult(result)
            } else if (result.type === 'recording_stopped') {
              console.log('🔇 后端停止录音')
              this.isRecording = false
              this.onStatusChange('stopped')
              this.onResult(result)
            } else {
              this.onResult(result)
            }
          } catch (error) {
            console.error('❌ 解析WebSocket消息失败:', error)
            console.error('📄 原始消息内容:', event.data)
            this.onError('解析服务器消息失败')
          }
        }

        this.ws.onerror = (error) => {
          console.error('🔴 WebSocket错误详情:', error)
          console.error('🔍 WebSocket状态:', this.ws?.readyState)
          console.error('🌐 尝试连接的URL:', wsUrl)
          console.error('📊 当前环境信息:', {
            userAgent: navigator.userAgent,
            protocol: window.location.protocol,
            hostname: window.location.hostname,
            port: window.location.port,
            href: window.location.href
          })
          
          this.onStatusChange('error')
          this.onError(`WebSocket连接错误 - URL: ${wsUrl}`)
          reject(new Error(`WebSocket连接失败: ${wsUrl}`))
        }

        this.ws.onclose = (event) => {
          console.log('🔒 WebSocket连接已关闭:', {
            code: event.code,
            reason: event.reason,
            wasClean: event.wasClean,
            url: wsUrl
          })
          
          // 详细的关闭码说明
          const closeReasons: { [key: number]: string } = {
            1000: '正常关闭',
            1001: '端点离开',
            1002: '协议错误',
            1003: '不支持的数据类型',
            1005: '未收到状态码',
            1006: '异常关闭',
            1007: '数据格式错误',
            1008: '策略违规',
            1009: '消息过大',
            1010: '扩展协商失败',
            1011: '服务器错误',
            1012: '服务重启',
            1013: '稍后重试',
            1014: '网关超时',
            1015: 'TLS握手失败'
          }
          
          const reasonText = closeReasons[event.code] || '未知原因'
          console.log(`📋 关闭原因: ${event.code} - ${reasonText}`)
          
          this.onStatusChange('stopped')
          this.isRecording = false
          
          if (event.code !== 1000) {
            const errorMsg = `连接意外关闭: ${event.code} - ${reasonText} (${event.reason || '无额外信息'})`
            console.error('❌', errorMsg)
            this.onError(errorMsg)
          }
        }

        // 添加连接超时检查
        const connectionTimeout = setTimeout(() => {
          if (this.ws && this.ws.readyState === WebSocket.CONNECTING) {
            console.error('⏰ WebSocket连接超时')
            this.ws.close()
            this.onStatusChange('error')
            reject(new Error('WebSocket连接超时'))
          }
        }, 10000) // 10秒超时

        // 连接成功后清除超时
        this.ws.addEventListener('open', () => {
          clearTimeout(connectionTimeout)
        })

      } catch (error) {
        console.error('💥 创建WebSocket连接失败:', error)
        console.error('🔍 错误详情:', {
          name: error instanceof Error ? error.name : 'Unknown',
          message: error instanceof Error ? error.message : String(error),
          stack: error instanceof Error ? error.stack : undefined
        })
        this.onStatusChange('error')
        reject(error)
      }
    })
  }

  /**
   * 发送控制消息给后端
   */
  async sendControlMessage(message: { type: string; [key: string]: any }): Promise<void> {
    if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
      throw new Error('WebSocket未连接，请先建立连接')
    }

    try {
      console.log('📤 发送控制消息:', message)
      this.ws.send(JSON.stringify(message))
    } catch (error) {
      console.error('❌ 发送控制消息失败:', error)
      throw new Error(`发送控制消息失败: ${error}`)
    }
  }

  /**
   * 开始录音（发送控制消息让后端处理）
   */
  async startRecording(): Promise<void> {
    await this.sendControlMessage({ type: 'start_recording' })
  }

  /**
   * 停止录音（发送控制消息）
   */
  async stopRecording(): Promise<void> {
    await this.sendControlMessage({ type: 'stop_recording' })
  }

  /**
   * 断开连接
   */
  disconnect(): void {
    try {
      if (this.ws) {
        console.log('🔌 正在断开WebSocket连接...')
        
        // 发送停止消息
        if (this.ws.readyState === WebSocket.OPEN) {
          this.ws.send(JSON.stringify({ type: 'stop' }))
        }
        
        this.ws.close(1000, '客户端主动断开')
        this.ws = null
      }
      
      this.isRecording = false
      console.log('✅ 连接已断开，资源已清理')
    } catch (error) {
      console.error('❌ 断开连接时出错:', error)
    }
  }

  /**
   * 获取录音状态
   */
  getRecordingStatus(): boolean {
    return this.isRecording
  }

  /**
   * 获取连接状态
   */
  getConnectionStatus(): 'disconnected' | 'connecting' | 'connected' | 'error' {
    if (!this.ws) return 'disconnected'
    
    switch (this.ws.readyState) {
      case WebSocket.CONNECTING:
        return 'connecting'
      case WebSocket.OPEN:
        return 'connected'
      case WebSocket.CLOSING:
      case WebSocket.CLOSED:
      default:
        return 'disconnected'
    }
  }

  private getWebSocketUrl(): string {
    const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
    const host = window.location.host
    
    // 开发环境判断
    if (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') {
      const backendPort = '8800'
      const backendHost = `${window.location.hostname}:${backendPort}`
      const wsUrl = `${protocol}//${backendHost}`
      console.log('🔧 开发环境WebSocket URL:', wsUrl)
      return wsUrl
    } else {
      // 生产环境，使用当前域名
      const wsUrl = `${protocol}//${host}`
      console.log('🌐 生产环境WebSocket URL:', wsUrl)
      return wsUrl
    }
  }

  getSessionId(): string {
    return this.sessionId
  }
}

/**
 * 检查浏览器对音频录制的支持
 */
export function checkAudioSupport(): {
  supported: boolean
  issues: string[]
} {
  console.log('🔍 开始检查音频支持...')
  const issues: string[] = []
  
  // 检查getUserMedia支持
  if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
    console.log('❌ 浏览器不支持麦克风访问')
    issues.push('浏览器不支持麦克风访问')
  } else {
    console.log('✅ 浏览器支持麦克风访问')
  }

  // 检查MediaRecorder支持
  if (!window.MediaRecorder) {
    console.log('❌ 浏览器不支持音频录制')
    issues.push('浏览器不支持音频录制')
  } else {
    console.log('✅ 浏览器支持音频录制')
  }

  // 检查WebSocket支持
  if (!window.WebSocket) {
    console.log('❌ 浏览器不支持WebSocket')
    issues.push('浏览器不支持WebSocket')
  } else {
    console.log('✅ 浏览器支持WebSocket')
  }

  // 检查AudioContext支持
  if (!window.AudioContext && !(window as any).webkitAudioContext) {
    console.log('❌ 浏览器不支持音频处理')
    issues.push('浏览器不支持音频处理')
  } else {
    console.log('✅ 浏览器支持音频处理')
  }

  const result = {
    supported: issues.length === 0,
    issues
  }
  
  console.log('🔍 音频支持检查完成:', result)
  return result
}

/**
 * 生成会话ID
 */
export function generateSessionId(): string {
  return `audio_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
} 